package pl.prv.polanie.client.widgets.schedule;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Klasa przedzialu czasu.
 * 
 * @author Janusz Prokulewicz
 * Created: Jun 4, 2008
 */
public class PeriodOfTime implements Comparable {
	
	private long startTime;
	private long duration;
	
	public PeriodOfTime() {
	}

	public PeriodOfTime(long startTime, long duration) {
		super();
		this.startTime = startTime;
		this.duration = duration;
	}

	public long getStartTime() {
		return startTime;
	}

	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}

	public long getDuration() {
		return duration;
	}

	public void setDuration(long duration) {
		this.duration = duration;
	}
	
	public long getEndTime() {
		return startTime + duration;
	}
	
	public int compareTo(Object o) {
	    final int BEFORE = -1;
	    final int EQUAL = 0;
	    final int AFTER = 1;
	    
	    PeriodOfTime pot;
	    if (o instanceof PeriodOfTime) {
			pot = (PeriodOfTime) o;

			//this optimization is usually worthwhile, and can
			//always be added
			if ( this == pot ) return EQUAL;
			
			//primitive numbers follow this form
			if (this.startTime < pot.startTime) return BEFORE;
			if (this.startTime > pot.startTime) return AFTER;
			if (this.startTime == pot.startTime) return EQUAL;
		};


		return EQUAL;
	}
	

	/**
	 * Periodsy musza byc posegregowane pod startTime.
	 * @param inputPeriods
	 * @return
	 */
	public static PeriodOfTime[] mergePeriodsOfTime(PeriodOfTime[] inputPeriods) {
		List potList = new ArrayList(); 
		
		for (int i = 0; i < inputPeriods.length; i++) {
			potList.add(inputPeriods[i]);
		}
		
		Collections.sort(potList);
		
		for (int i = potList.size()-1; i >= 0; i--) {
			if (i-1 > 0) {
				PeriodOfTime curPot = (PeriodOfTime)potList.get(i);
				PeriodOfTime prevPot = (PeriodOfTime)potList.get(i-1);
				if (arePeriodsOfTimeAbleToMerge(curPot, prevPot)) {
					long laterEndTime = Math.max(curPot.getEndTime(), prevPot.getEndTime());
					prevPot.setDuration(laterEndTime - prevPot.getStartTime());
					
					//usuwamy zmerge'owany pot
					potList.remove(i);
				}
			}
		}

		return (PeriodOfTime[])potList.toArray(new PeriodOfTime[0]);
	}
	
	/**
	 * Funkcja zwraca true, gdy dwa przedzialy czasu sie zazebiaja lub gdy jeden konczy sie tam, gdzie nastepny sie zaczyna.
	 * @param pot1
	 * @param pot2
	 * @return
	 */
	public static boolean arePeriodsOfTimeAbleToMerge(PeriodOfTime pot1, PeriodOfTime pot2) {
		if (pot1.getStartTime() >= pot2.getStartTime() && pot1.getStartTime() <= pot2.getEndTime()) {
			return true;
		}
		
		if (pot2.getStartTime() >= pot1.getStartTime() && pot2.getStartTime() <= pot1.getEndTime()) {
			return true;
		}
		
		return false;
	}
	
//	public static void main(String[] args) {
//		///KOD TESTUJACY
//		PeriodOfTime pot1 = new PeriodOfTime(200, 100);
//		
//		PeriodOfTime pot2;
//		
//		
//		pot2 = new PeriodOfTime(10, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test1: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//		
//		pot2 = new PeriodOfTime(100, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test2: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//		
//		pot2 = new PeriodOfTime(150, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test3: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//
//		pot2 = new PeriodOfTime(210, 80);
//		System.out.println("PeriodOfTime areAbleToMerge test4: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//
//		pot2 = new PeriodOfTime(250, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test5: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//		
//		pot2 = new PeriodOfTime(300, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test6: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//		
//		pot2 = new PeriodOfTime(350, 100);
//		System.out.println("PeriodOfTime areAbleToMerge test7: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//		
//		pot2 = new PeriodOfTime(150, 200);
//		System.out.println("PeriodOfTime areAbleToMerge test8: " + arePeriodsOfTimeAbleToMerge(pot1, pot2));
//	}
}
